package com.ruoyi.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.SysGeographical;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.security.annotation.PreAuthorize;

import com.ruoyi.system.domain.vo.GeographicalAddVo;
import com.ruoyi.system.domain.vo.GeographicalEditVo;
import com.ruoyi.system.domain.vo.GeographicalListVo;
import com.ruoyi.system.domain.vo.MapAddressDataVo;
import com.ruoyi.system.service.ISysGeographicalService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * 地理位置信息Controller
 *
 * @author yfkj
 * @date 2021-10-12
 */
@RestController
@RequestMapping("/system/SysGeographical")
public class SysGeographicalController extends com.ruoyi.common.core.web.controller.BaseController {
    @Autowired
    private ISysGeographicalService sysGeographicalService;
    @Autowired
    private RestTemplateBuilder restTemplateBuilder;

    /**
     * 查询区域地址信息树表
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "system:SysGeographical:list")
    @GetMapping("/list")
    @ApiOperation("查询区域地址信息树表")
    public com.ruoyi.common.core.web.page.TableDataInfo list(GeographicalListVo vo) {
        SysGeographical sysGeographical = new SysGeographical();
        BeanUtils.copyProperties(vo, sysGeographical);
        startPage();
        List<SysGeographical> list = sysGeographicalService.selectSysGeographicalList(sysGeographical);
        List<SysGeographical> geographicalTree = sysGeographicalService.buildGeographicalTree(list);
        return getDataTable(geographicalTree);
    }

    /**
     * 导出地理位置信息列表
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "system:SysGeographical:export")
    @Log(title = "地理位置信息", businessType = BusinessType.EXPORT)
    @PostMapping(value="/export", produces = "application/octet-stream")
    //@ApiOperation("导出地理位置信息列表")
    public void export(HttpServletResponse response, SysGeographical sysGeographical) throws IOException {
        List<SysGeographical> list = sysGeographicalService.selectSysGeographicalList(sysGeographical);
        com.ruoyi.common.core.utils.poi.ExcelUtil<SysGeographical> util = new com.ruoyi.common.core.utils.poi.ExcelUtil<SysGeographical>(SysGeographical.class);
        util.exportExcel(response, list, "地理位置信息数据");
    }

    /**
     * 获取区域地址信息详细信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "system:SysGeographical:query")
    @GetMapping(value = "/{geographicalId}")
    @ApiOperation("获取区域地址信息详细信息,geographicalId-区域地址ID-Long-必填")
    public com.ruoyi.common.core.web.domain.AjaxResult getInfo(@PathVariable("geographicalId") Long geographicalId) {
        return com.ruoyi.common.core.web.domain.AjaxResult.success(sysGeographicalService.selectSysGeographicalByGeographicalId(geographicalId));
    }

    /**
     * 新增同级区域地址信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "system:SysGeographical:add")
    @Log(title = "区域地址信息", businessType = BusinessType.INSERT)
    @PostMapping("/addSibling")
    @ApiOperation("新增同级区域地址信息")
    public com.ruoyi.common.core.web.domain.AjaxResult addSibling(@RequestBody GeographicalAddVo vo) {
        SysGeographical sysGeographical = new SysGeographical();
        BeanUtils.copyProperties(vo, sysGeographical);
        if (sysGeographicalService.getGeographicalByCode(vo.getGeographicalCode()) != null) {
            return com.ruoyi.common.core.web.domain.AjaxResult.error("该区域码已存在！");
        }
        if (sysGeographicalService.getGeographicalByName(vo.getGeographicalName()) != null) {
            return com.ruoyi.common.core.web.domain.AjaxResult.error("该区域名称已存在！");
        }
        SysGeographical geographical = sysGeographicalService.getOne(new QueryWrapper<SysGeographical>()
                .eq(SysGeographical.GEOGRAPHICAL_ID, vo.getGeographicalId()), false);
        if (geographical != null){
            SysGeographical parent = sysGeographicalService.selectSysGeographicalByGeographicalId(geographical.getParentId());
            if (parent != null){
                sysGeographical.setGeographicalFullName(parent.getGeographicalFullName() + vo.getGeographicalName());
            } else {
                //新增的区域属于顶级节点
                sysGeographical.setGeographicalFullName(vo.getGeographicalName());
            }
            sysGeographical.setAncestors(geographical.getAncestors());
            sysGeographical.setParentId(geographical.getParentId());
        } else {
            //第一次新增区域信息
            sysGeographical.setGeographicalFullName(vo.getGeographicalName());
            sysGeographical.setAncestors("0");
            sysGeographical.setParentId(0L);
        }
        return toAjax(sysGeographicalService.insertSysGeographical(sysGeographical));
    }

    /**
     * 新增下级区域地址信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "system:SysGeographical:add")
    @Log(title = "区域地址信息", businessType = BusinessType.INSERT)
    @PostMapping("/addLower")
    @ApiOperation("新增下级区域地址信息")
    public com.ruoyi.common.core.web.domain.AjaxResult addLower(@RequestBody GeographicalAddVo vo) {
        SysGeographical sysGeographical = new SysGeographical();
        BeanUtils.copyProperties(vo, sysGeographical);
        if (sysGeographicalService.getGeographicalByCode(vo.getGeographicalCode()) != null) {
            return com.ruoyi.common.core.web.domain.AjaxResult.error("该区域码已存在！");
        }
        if (sysGeographicalService.getGeographicalByName(vo.getGeographicalName()) != null) {
            return com.ruoyi.common.core.web.domain.AjaxResult.error("该区域名称已存在！");
        }
        SysGeographical geographical = sysGeographicalService.getOne(new QueryWrapper<SysGeographical>()
                .eq(SysGeographical.GEOGRAPHICAL_ID, vo.getParentId()), false);
        sysGeographical.setGeographicalFullName(geographical.getGeographicalFullName() + vo.getGeographicalName());
        sysGeographical.setAncestors(geographical.getAncestors() + "," + vo.getParentId());
        return toAjax(sysGeographicalService.insertSysGeographical(sysGeographical));
    }

    /**
     * 修改区域地址信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "system:SysGeographical:edit")
    @Log(title = "区域地址信息", businessType = BusinessType.UPDATE)
    @PutMapping
    @ApiOperation("修改区域地址信息")
    public com.ruoyi.common.core.web.domain.AjaxResult edit(@RequestBody GeographicalEditVo vo) {
        SysGeographical sysGeographical = new SysGeographical();
        BeanUtils.copyProperties(vo, sysGeographical);
        SysGeographical geographical = sysGeographicalService.getOne(new QueryWrapper<SysGeographical>()
                .eq(SysGeographical.GEOGRAPHICAL_ID, vo.getGeographicalId()), false);
        SysGeographical parent = sysGeographicalService.getOne(new QueryWrapper<SysGeographical>()
                .eq(SysGeographical.GEOGRAPHICAL_ID, geographical.getParentId()), false);
        if (parent != null) {
            sysGeographical.setGeographicalFullName(parent.getGeographicalFullName() + vo.getGeographicalName());
        } else {
            sysGeographical.setGeographicalFullName(vo.getGeographicalName());
        }

        return toAjax(sysGeographicalService.updateSysGeographical(sysGeographical));
    }

    /**
     * 删除区域地址信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "system:SysGeographical:remove")
    @Log(title = "区域地址信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{geographicalId}")
    @ApiOperation("删除区域地址信息(支持批量删除),geographicalId-区域地址ID-Long-必填")
    public com.ruoyi.common.core.web.domain.AjaxResult remove(@PathVariable Long geographicalId) {
        return toAjax(sysGeographicalService.deleteSysGeographicalByGeographicalId(geographicalId));
    }

    /**
     * 获取区域地址下拉树表
     * @return
     */
    @GetMapping("/getGeographicalTree")
    @ApiOperation("获取区域地址下拉树表")
    public com.ruoyi.common.core.web.domain.AjaxResult getGeographicalTree(){
        List<SysGeographical> list = sysGeographicalService.selectSysGeographicalList(null);
        List<TreeSelect> treeSelects = sysGeographicalService.buildGeographicalTreeSelect(list);
        return com.ruoyi.common.core.web.domain.AjaxResult.success(treeSelects);
    }

    /**
     * 根据上级区域ID获取上级区域名(用于在修改页面显示上级区域名称)
     * @param parentId
     * @return
     */
    @GetMapping("/getGeographicalNameById")
    @ApiOperation("根据上级区域ID获取上级区域名(用于在修改页面显示上级区域名称),parentId-上级区域ID-Long-必填")
    public com.ruoyi.common.core.web.domain.AjaxResult getGeographicalNameById(Long parentId){
        if (parentId != null && parentId != 0){
            SysGeographical geographical = sysGeographicalService.getGeographicalById(parentId);
            return com.ruoyi.common.core.web.domain.AjaxResult.success(geographical.getGeographicalFullName());
        }
        return com.ruoyi.common.core.web.domain.AjaxResult.success("无上级区域");
    }

    //用来导入地图的数据
    @GetMapping("/importMapData")
    public com.ruoyi.common.core.web.domain.AjaxResult importMapData() {
        RestTemplate restTemplate = restTemplateBuilder.build();
        String targetUrl = "https://gw.alipayobjects.com/os/alisis/geo-data-v0.1.1/administrative-data/area-list.json";
        List result = restTemplate.getForObject(targetUrl, List.class);
        List<MapAddressDataVo> vos = new ArrayList<>();
        if (result != null) {
            for (Object o : result) {
                LinkedHashMap map = (LinkedHashMap) o;
                Object name = map.get("name");
                Object level = map.get("level");
                Object adcode = map.get("adcode");
                Object lng = map.get("lng");
                Object lat = map.get("lat");
                Object childrenNum = map.get("childrenNum");
                Object parent = map.get("parent");
                MapAddressDataVo vo = new MapAddressDataVo();
                vo.setName((String) name);
                vo.setLevel((String) level);
                vo.setAdcode(adcode);
                vo.setLng((Double) lng);
                vo.setLat((Double) lat);
                vo.setChildrenNum((Integer) childrenNum);
                vo.setParent((Integer) parent);
                if (parent != null || name.equals("中华人民共和国")) {
                    vos.add(vo);
                }
            }
        }
        //开始往数据库插入数据
        for (MapAddressDataVo vo : vos) {
            String adcode = vo.getAdcode().toString();
            String parent = null;
            QueryWrapper<SysGeographical> wrapper = new QueryWrapper<>();
            if (vo.getParent() != null) {
                parent = vo.getParent().toString();
                wrapper.eq(SysGeographical.GEOGRAPHICAL_CODE, parent);
            }
            SysGeographical sysGeographical = new SysGeographical();
            SysGeographical address;
            List<SysGeographical> geographicals = sysGeographicalService.list(wrapper);
            if (geographicals.size() > 1) {
                wrapper.eq(SysGeographical.LEVEL, "city");
                address = sysGeographicalService.getOne(wrapper, false);
            } else {
                address = sysGeographicalService.getOne(wrapper);
            }
            if (parent != null) {
                sysGeographical.setParentId(address.getGeographicalId());
                sysGeographical.setAncestors(address.getAncestors() + "," + address.getGeographicalId());
                sysGeographical.setGeographicalFullName(address.getGeographicalFullName() + vo.getName());
            } else {
                sysGeographical.setParentId(0L);
                sysGeographical.setAncestors("0");
                sysGeographical.setGeographicalFullName(vo.getName());
            }
            sysGeographical.setGeographicalCode(adcode);
            sysGeographical.setGeographicalName(vo.getName());
            sysGeographical.setLng(vo.getLng());
            sysGeographical.setLat(vo.getLat());
            sysGeographical.setChildrenNum(vo.getChildrenNum());
            sysGeographical.setLevel(vo.getLevel());
            sysGeographical.setParent(vo.getParent());
            sysGeographicalService.save(sysGeographical);
        }
        return com.ruoyi.common.core.web.domain.AjaxResult.success();
    }

    //用于远程调用，查询区域地址列表
    @GetMapping("/getGeographicals")
    public R<List<SysGeographical>> getGeographicals() {
        return R.ok(sysGeographicalService.list());
    }
}
